﻿/*
 * Module Name: Equation.cs
 * 
 * Purpose: This is used to create a dynamic equation from a string
 * 
 * Created by: Chris Tisdale
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
using System.Threading;
using Common_Code.Heler_Functions;

namespace Common_Code.Math_Extensions
{
    public class Equation
    {
        private Expression<Func<double, double>> equat;

        private String express;
        private char[] sep = { '+', '*', '/', '-', '^', '(', ')', '[', ']', 'x', 'y', 'z', 'X', 'Y', 'Z' };

        public Equation(Expression<Func<double, double>> func)
        {
            equat = func;
        }

        public Equation(String equation)
        {
            var temp = equation.SplitAndKeep(sep);
            var arrayTemp = temp.ToArray<String>();
            var retVal = stringToEquation(arrayTemp, 0);
            if (retVal.CompareTo("Pass") != 0)
            {
                throw new System.InvalidOperationException(retVal);
            }
            express = equation;
        }
        
        private String stringToEquation(String[] parts, int loc)
        {
            var retVal = "Pass";
            //express = parts;
            //IEnumerable<String> parts = val.SplitAndKeep(sep);
            double num;
            //int openParenthises = 0;
            for(var count = loc; count < parts.Length; count++)
            {
                if (parts[count].IndexOf("(") != -1 || parts[count].IndexOf("[") != -1)
                {
                    //openParenthises++;
                    loc++;
                    stringToEquation(parts, loc);
                }
                else if (parts[count].IndexOf(")") != -1 || parts[count].IndexOf("]") != -1)
                {
                    //openParenthises--;
                    loc--;
                    if (loc < 0)
                    {
                        retVal = "Fail at " + parts[count] + " with a missing open prarenthasis";
                        return retVal;
                    }
                    stringToEquation(parts, loc);
                }
                else if (parts[count].IndexOf("cos") != -1)
                {

                }
                else if (parts[count].IndexOf("sin") != -1)
                {

                }
                else if (parts[count].IndexOf("e") != -1)
                {

                }
                else if (parts[count].IndexOf("tan") != -1)
                {

                }
                else if (parts[count].IndexOf("sec") != -1)
                {

                }
                else if (parts[count].IndexOf("csc") != -1)
                {

                }
                else if (parts[count].IndexOf("sqrt") != -1)
                {

                }
                else if (parts[count].IndexOf("x") != -1)
                {

                }
                else if (parts[count].IndexOf("y") != -1)
                {

                }
                else if (parts[count].IndexOf("z") != -1)
                {

                }
                else if (double.TryParse(parts[count], out num))
                {

                }
                else
                {
                    //Comment out for build errors fix and recomment back in
                    /*
                    int setUpIndex = -1;
                    for (int i = 0; i < 5; i++)
                    {
                        if(parts[count].IndexOf(char[i]))
                        {
                            setUpIndex = i;
                        }
                    }
                    
                    if (setUpIndex != -1)
                    {

                    }
                    else
                    {
                        if (mult)
                        {
                            retVal += " and " + parts[count];
                        }
                        else
                        {
                            retVal = "Fail at " + parts[count];
                            mult = true;
                        }
                    }
                    */
                }
            }
            return retVal;
        }

        public double evalAt(double val)
        {
            return -1;
        }

        public double evalAt(double val1, double val2)
        {
            return -1;
        }

        public double evalAt(double val1, double val2, double val3)
        {
            return -1;
        }

        public Expression<Func<double, double>> getExpressionEquation()
        {
            return equat;
        }

        public String getExpressionString()
        {
            return express;
        }
    }
}
